﻿#ifndef __INC_QG_OGL_EXT_H__
#define __INC_QG_OGL_EXT_H__

#ifdef _MSC_VER
#pragma once
#endif

namespace _ogl
{
	// 캡스
	enum CapsIndex
	{
		QGLX_ARB_PROVOKING_VERTEX,
		QGLX_EXT_PROVOKING_VERTEX,
		QGLX_EXT_DRAW_BUFFERS_2,
		QGLX_ARB_DRAW_BUFFERS_BLEND,
		QGLX_AMD_DRAW_BUFFERS_BLEND,
		QGLX_EXT_SEPARATE_SPECULAR_COLOR,
		QGLX_EXT_BLEND_SUBTRACT,
		QGLX_EXT_BLEND_LOGIC_OP,
		QGLX_NVX_GPU_MEMORY_INFO,
		QGLX_ATI_MEMINFO,
		QGLX_ARB_MULTITEXTURE,
		QGLX_ARB_TEXTURE_COMPRESSION,
		QGLX_ARB_VERTEX_SHADER,
		QGLX_EXT_TEXTURE_LOD_BIAS,
		QGLX_ARB_DRAW_BUFFERS,
		QGLX_ATI_DRAW_BUFFERS,
		QGLX_ARB_SHADING_LANGUAGE_100,
		QGLX_ARB_OCCLUSION_QUERY,
		QGLX_NV_OCCLUSION_QUERY,
		QGLX_AMD_BLEND_MINMAX_FACTOR,
		QGLX_EXT_CLIP_VOLUME_HINT,
		QGLX_ARB_TEXTURE_ENV_COMBINE,
		QGLX_EXT_TEXTURE_ENV_COMBINE,
		QGLX_EXT_TEXTURE_FILTER_ANISOTROPIC,
		QGLX_MESA_PACK_INVERT,
		QGLX_ARB_TEXTURE_NON_POWER_OF_TWO,
		QGLX_EXT_PACKED_DEPTH_STENCIL,
		QGLX_MAX_VALUE
	};

	//
	extern bool GLCS[QGLX_MAX_VALUE];

	//
	inline bool TestGLCS(kint nth) { return GLCS[nth]; }

	// 텍스쳐
	extern void QglActiveTexture(GLenum texture);
	extern void QglClientActiveTexture(GLenum texture);
	extern void QglCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data);
	extern void QglGenerateMipmap(GLenum target);

	// 블렌드
	extern void QglBlendEquation(GLenum mode);
	extern void QglBlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
	extern void QglEnableIndexed(GLenum target, GLuint index);
	extern void QglDisableIndexed(GLenum target, GLuint index);
	extern void QglColorMaskIndexed(GLuint buf, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
	extern void QglBlendFuncIndexed(GLuint buf, GLenum src, GLenum dst);
	extern void QglBlendEquationIndexed(GLuint buf, GLenum mode);

	// 레이아웃	
	extern void QglEnableVertexArray(GLuint index);
	extern void QglDisableVertexArray(GLuint index);
	extern void QglSecondaryColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
	extern void QglVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* pointer);

	// FBO
	extern void QglGenFramebuffers(GLsizei n, GLuint* framebuffers);
	extern void QglBindFramebuffer(GLenum target, GLuint framebuffer);
	extern void QglDeleteFramebuffers(GLsizei n, const GLuint* framebuffers);
	extern GLenum QglCheckFramebufferStatus(GLenum target);
	extern void QglFramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
	extern void QglFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
	extern void QglFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
	extern void QglGenRenderbuffers(GLsizei n, GLuint* renderbuffers);
	extern void QglBindRenderbuffer(GLenum target, GLuint renderbuffer);
	extern void QglDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers);
	extern void QglRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
	extern void QglFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
	extern void QglGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params);
	extern void QglGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params);

	// 프로그램과 세이더
	extern GLuint QglCreateProgram(void);
	extern void QglDeleteProgram(GLuint object);
	extern void QglAttachShader(GLuint program, GLuint shader);
	extern void QglDetachShader(GLuint program, GLuint shader);
	extern void QglGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
	extern void QglGetProgramiv(GLuint program, GLenum type, GLint* param);
	extern void QglGetProgramInfoLog(GLuint program, GLsizei maxLength, GLsizei* length, GLchar* infoLog);
	extern void QglGetActiveAttrib(GLuint program, GLuint index, GLsizei maxlength, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
	extern void QglGetActiveUniform(GLuint program, GLuint index, GLsizei maxlength, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
	extern GLint QglGetAttribLocation(GLuint program, const GLchar *name);
	extern GLint QglGetUniformLocation(GLuint program, const GLchar* name);

	extern GLuint QglCreateShader(GLenum shaderType);
	extern void QglShaderSource(GLuint shader, GLsizei numOfStrings, const char** strings, const GLint* lenOfStrings);
	extern void QglCompileShader(GLuint shader);
	extern void QglLinkProgram(GLuint program);
	extern void QglUseProgram(GLuint prog);
	extern void QglDeleteShader(GLuint shader);
	extern void QglGetShaderiv(GLuint shader, GLenum type, GLint* param);
	extern void QglGetShaderInfoLog(GLuint shader, GLsizei maxLength, GLsizei* length, GLchar* infoLog);
	
	extern void QglUniform1fv(GLint loc, GLsizei count, const GLfloat* v);
	extern void QglUniform2fv(GLint loc, GLsizei count, const GLfloat* v);
	extern void QglUniform3fv(GLint loc, GLsizei count, const GLfloat* v);
	extern void QglUniform4fv(GLint loc, GLsizei count, const GLfloat* v);
	extern void QglUniform1iv(GLint loc, GLsizei count, const GLint* v);
	extern void QglUniform2iv(GLint loc, GLsizei count, const GLint* v);
	extern void QglUniform3iv(GLint loc, GLsizei count, const GLint* v);
	extern void QglUniform4iv(GLint loc, GLsizei count, const GLint* v);
	extern void QglUniformMatrix2fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat* v);
	extern void QglUniformMatrix3fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat* v);
	extern void QglUniformMatrix4fv(GLint loc, GLsizei count, GLboolean transpose, const GLfloat* v);

	extern void QglProgramParameteri(GLhandleARB program, GLenum pname, GLint value);

	// 버퍼
	extern void QglGenBuffers(GLsizei n, GLuint* buffers);
	extern void QglBindBuffer(GLenum target, GLuint buffer);
	extern void QglDeleteBuffers(GLsizei n, const GLuint* buffers);
	extern void QglBufferData(GLenum target, GLsizeiptrARB size, const GLvoid* data, GLenum usage);
	extern void QglBufferSubData(GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid* data);
	extern void QglGetBufferSubData(GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid* data);
	extern void* QglMapBuffer(GLenum target, GLenum access);
	extern GLboolean QglUnmapBuffer(GLenum target);
	extern GLboolean QglIsBuffer(GLuint buffer);
	extern void QglDrawBuffers(GLsizei n, const GLenum* bufs);
	extern void QglProvokingVertex(GLenum mode);

	// 포인트
	extern void QglPointParameterf(GLint loc, GLfloat f);
	extern void QglPointParameterfv(GLint loc, const GLfloat* v);

	// 스텐실
	extern void QglStencilFuncSeparate(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
	extern void QglStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
	extern void QglActiveStencilFace(GLenum face);

	// 오클루전
	extern void QglGenQueries(GLsizei n, GLuint* ids);
	extern void QglDeleteQueries(GLsizei n, const GLuint* ids);
	extern GLboolean QglIsQuery(GLuint id);
	extern void QglBeginQuery(GLenum target, GLuint id);
	extern void QglEndQuery(GLenum target);
	extern void QglGetQueryiv(GLenum target, GLenum pname, GLint* params);
	extern void QglGetQueryObjectiv(GLuint id, GLenum pname, GLint* params);
	extern void QglGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params);

	// 기타
	extern void QglSwapInterval(int interval);
	extern void QglTestGlFunc();

	// 초기화
	extern void InitializeExtension();
	extern void InitializeCaps(qgDevCaps& pc, bool usestencil);
}

#endif	// __INC_QG_OGL_EXT_H__
